package com.camemax.netty.nio;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

/**
 * Channel本地文件读写测试：
 * 使用ByteBuffer（缓冲）与FileChannel（通道），将file01.txt文件的内容写到file02.txt中
 */
public class NIOChannelForFileCopy {
    static String LOCAL_FILE_NAME = "D:\\Javas\\netty\\files\\file01.txt";
    static String TARGET_FILE_NAME = "D:\\Javas\\netty\\files\\file02.txt";
    public static void main(String[] args) {
        // myNIO();
        atguiguNIO();
    }
    static void myNIO() {
        // 1、加载指定文件到缓冲区中
        // 1.1、获取文件对象
        File localFile = new File(LOCAL_FILE_NAME);
        // 1.2、文件创建校验
        FilePathCheck.checkDirectories(localFile);
        // 1.3、定义缓冲区默认大小
        ByteBuffer buffer = ByteBuffer.allocate(512);
        try {
            // 1.4、使用FileInputStream流读取文件，并获取其Channel，加载到Buffer缓冲中
            FileChannel channel = new FileInputStream(localFile).getChannel();
            while (true) {
                int read = channel.read(buffer);
                if (read == -1) { // 读取完毕
                    break;
                }
            }
            System.out.println("缓冲读取文件完毕!");
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 2、读取缓冲区中的数据，写入到另外一个文件中
        // 2.1、获取另外一个文件对象
        File targetFile = new File(TARGET_FILE_NAME);

        // 2.2、文件创建校验
        FilePathCheck.checkDirectories(targetFile);
        try {
            FileChannel channel = new FileOutputStream(targetFile).getChannel();
            buffer.flip(); // 读写切换
            channel.write(buffer);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    static void atguiguNIO() {
        File localFile = new File(LOCAL_FILE_NAME);
        File targetFile = new File(TARGET_FILE_NAME);

        FilePathCheck.checkDirectories(localFile);
        FilePathCheck.checkDirectories(targetFile);

        ByteBuffer buffer = ByteBuffer.allocate(512);
        try {
            FileChannel inputChannel = new FileInputStream(localFile).getChannel();
            FileChannel outputChannel = new FileOutputStream(targetFile).getChannel();

            while (true) {
                buffer.clear(); // 缓冲初始化，否则会因position = limit导致返回值为0
                int read = inputChannel.read(buffer); // 将获取到文件字节流的管道写入缓冲区
                if (read == -1) {
                    break;
                }
                buffer.flip(); // 读写切换（将position = 0，即从缓冲区第0下标开始读）
                outputChannel.write(buffer); // 调用指定文件输出流的管道写入缓冲区内容
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
